package com.hyperboost.framework.aspectj;

import com.hyperboost.common.annotation.AutoFill;
import com.hyperboost.common.core.domain.BaseEntity;
import com.hyperboost.common.enums.OperationType;
import com.hyperboost.common.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 数据库公共字段自动填充处理
 */
@Slf4j
@Aspect
@Component
public class AutoFillAspect {

    /**
     * 切入点
     */
    @Pointcut("@annotation(com.hyperboost.common.annotation.AutoFill)")
    public void autoFillPointcut() {
    }

    /**
     * 前置通知
     */
    @Before("autoFillPointcut()")
    public void autoFillBefore(JoinPoint joinPoint) {
        // 获取方法签名对象
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        // 获取方法注解对象
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);

        // 获取数据库操作类型
        OperationType operationType = autoFill.value();

        // 获取被拦截方法参数
        Object[] args = joinPoint.getArgs();

        // 约定第一个参数为实体对象
        Object entity = args[0];

        // 获取当前用户信息
        String username = SecurityUtils.getUsername();

        // 填充公共字段

            if (operationType == OperationType.INSERT){
                // 新增操作，设置创建人和更新人公共字段
                try {
                    // 获取实体类中set方法
                    Method setCreateBy = entity.getClass().getMethod("setCreateBy", String.class);
                    Method setUpdateBy = entity.getClass().getMethod("setUpdateBy", String.class);

                    // 通过反射设置创建人和更新人
                    setCreateBy.invoke(entity, username);
                    setUpdateBy.invoke(entity, username);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }else if (operationType == OperationType.UPDATE){
                // 更新操作，设置更新人公共字段
                try {
                    // 获取实体类中set方法
                    Method setUpdateBy = entity.getClass().getMethod("setUpdateBy", String.class);
                    // 通过反射设置更新人
                    setUpdateBy.invoke(entity, username);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    }
}
